from model.park_spider import ParkSpider
from model.park_platform import ParkPlatform
from model.car_number import CarNumber
from model.result import Result

import datetime
import random
import hashlib
import json
import requests
from Crypto.Cipher import AES
from binascii import b2a_hex
import dateutil.parser as dateutil
import spider_config

import common.http as http


def aes(text, key):
    text = text.encode("utf-8")
    key_bytes = key.encode("utf-8")
    cryptor = AES.new(key_bytes, AES.MODE_ECB)
    pad = 16 - len(text) % 16
    text = text + (chr(pad) * pad).encode("utf-8")
    ciphertext = cryptor.encrypt(text)

    return b2a_hex(ciphertext).decode("utf-8")


def sign(s):
    n = "W9cE5d4q0df9GjeBaR16a5B56Z1V51i7"
    t = []
    for key in sorted(s.keys()):
        if s[key] is not None:
            t.append(key + "=" + str(s[key]))
    n = "&".join(t) + "&" + n
    m = hashlib.md5()
    m.update(n.encode("utf-8"))
    return m.hexdigest().upper()


def encrpty(s):
    c = "L2kJs2aH9zT3X9SF"
    r = aes(s, c)
    return r


def transformRequest(e):
    a = int(datetime.datetime.now().timestamp() * 1000)
    i = str(random.randint(10000000, 99999999))[:7]
    c = {"signType": "MD5", "timestamp": a, "nonce": i + str(a)}
    s = {**e, **c}
    s["sign"] = sign(s)

    return {"data": encrpty(json.dumps(s))}


class JieParkSpider(ParkSpider):
    def platform(self) -> ParkPlatform:
        return ParkPlatform(spider_config.jie_park_id)

    def query(self, carNumber: CarNumber):
        result = Result()
        result.platform = self.platform()
        result.car_number = carNumber

        e = {
            "isNewReport": 1,
            "userId": self.getAccount(),
            "carNo": f"{carNumber.province}-{carNumber.city}{carNumber.number}",
            "privacyOption": 1,
            "latitude": None,
            "longitude": None,
            "distance": 3000,
            "unionId": "",
            "openId": "",
            "orderVersion": "2.1",
        }

        requestBody = transformRequest(e)

        headers = {
            "Host": "sytgate.jslife.com.cn",
            "Accept": "application/json, text/plain, */*",
            "Content-Type": "application/json;charset=UTF-8",
            "User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36 Edg/107.0.1418.35",
            "Referer": "https://www.jslife.com.cn/jtc-h5/pay/car-no-pay.html",
        }

        url = "https://sytgate.jslife.com.cn/core-gateway/order/carno/pay/index"

        rsp = http.post(
            url,
            proxies=self.getProxy(),
            data=json.dumps(requestBody),
            headers=headers,
            timeout=self.getTimeout(),
        )

        if rsp.status_code != 200:
            result.error_code = rsp.status_code
            result.message = rsp.text
            result.success = False
            return result

        try:
            rspJson = rsp.json()
        except:
            raise json.JSONDecodeError("捷停车json解析失败", rsp.text, 0)

        result.error_code = rspJson["resultCode"]
        result.success = rspJson["success"]
        result.message = rspJson["message"] if "message" in rspJson else ""

        if not result.success and (
            len(result.error_code) == 4
            or result.error_code == "123012"
            or result.error_code == "120003"
        ):
            raise requests.exceptions.ProxyError(f"捷停车反爬: {result.error_code}")

        if not result.success:
            return result

        if (
            "parkAdditionalInfo" not in rspJson["obj"]
            or not rspJson["obj"]["parkAdditionalInfo"]["latitude"]
            or not rspJson["obj"]["parkAdditionalInfo"]["longitude"]
            or not rspJson["obj"]["startTime"]
            or not rspJson["obj"]["endTime"]
            # or rspJson["obj"]["retmsg"] == "非临时卡"
            or rspJson["obj"]["retmsg"] == "未入场"
            or rspJson["obj"]["startTime"] == rspJson["obj"]["endTime"]
        ):
            result.success = False
            return result

        result.enter_time = dateutil.parse(rspJson["obj"]["startTime"])

        if not result.enter_time or result.enter_time > datetime.datetime.now():
            result.success = False
            return result

        result.price = rspJson["obj"]["totalFee"]

        url = "https://sytgate.jslife.com.cn/core-gateway/cwzg/v2/search_park"

        headers = {
            "Content-Type": "application/json;charset=UTF-8",
            "Host": "sytgate.jslife.com.cn",
        }
        data = {
            "latitude": rspJson["obj"]["parkAdditionalInfo"]["latitude"],
            "longitude": rspJson["obj"]["parkAdditionalInfo"]["longitude"],
            "pageIndex": 1,
            "pageSize": 1,
        }

        rsp = http.post(
            url,
            proxies=self.getProxy(),
            headers=headers,
            data=json.dumps(data),
            timeout=self.getTimeout(),
        )

        if rsp.status_code != 200:
            result.error_code = rsp.status_code
            result.message = rsp.text
            result.success = False
            return result

        try:
            rspJson = rsp.json()
        except:
            raise json.JSONDecodeError("捷停车json解析失败", rsp.text, 0)

        if rspJson["code"] != "0":
            result.remark = "查询停车场信息失败"
            return result

        if "data" not in rspJson or len(rspJson["data"]) == 0:
            result.remark = "车场信息为空"
            return result

        data = rspJson["data"][0]
        result.park_name = data["parkName"]

        try:
            result.park_name = f'{data["parkName"]} （{data["canton"]+data["address"]}）'
        except:
            pass

        return result
